package com.fitso.model.bean.journal;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.joda.time.DateTime;

import com.fitso.model.bean.ModelBean;
import com.fitso.model.bean.User;
import com.fitso.model.bean.measure.energy.Calorie;
import com.fitso.model.bean.nutrition.Food;

public class FoodJournal extends ModelBean implements Serializable {
	// Only change on breaking changes, i.e., removing fields
	private static final long serialVersionUID = 1L;
	
	private List<FoodJournalEntry> _entries = new ArrayList<FoodJournalEntry>();

	// Keeps track of removed entries for undo, auditing and syncing
	private List<FoodJournalEntry> _removedEntries = new ArrayList<FoodJournalEntry>();

	public FoodJournal() {}

	public FoodJournal(List<FoodJournalEntry> entries) {
		_entries = entries;
	}

	public void addEntry(FoodJournalEntry entry) {
		_entries.add(entry);
	}

	public void addEntry(User user, DateTime at, Food food) {
		addEntry(new FoodJournalEntry(user, at, food));
	}

	public boolean equals(Object o) {
		if (o == null) {
			return false;
		}
		if (o == this) {
			return true;
		}
		if (o.getClass() != getClass()) {
			return false;
		}

		FoodJournal other = (FoodJournal) o;
		return new EqualsBuilder().append(_entries, other._entries).isEquals();
	}

	public List<FoodJournalEntry> getEntries() {
		return _entries == null ? Collections.<FoodJournalEntry>emptyList(): _entries;
	}

	public List<FoodJournalEntry> getRemovedEntries() {
		return _removedEntries;
	}

	public Calorie getTotalCalories() {
		Calorie totalCalories = new Calorie();

		for (FoodJournalEntry fje : _entries) {
			totalCalories = (Calorie) totalCalories.add(fje.getFood().getCalories());
		}
		return totalCalories;
	}

	public int hashCode() {
		return new HashCodeBuilder().append(_entries).toHashCode();
	}

	public boolean isEmpty() {
		return _entries.isEmpty();
	}

	public void removeEntry(FoodJournalEntry entry) {
		_removedEntries.add(entry);
		_entries.remove(entry);
	}

	public void setEntries(List<FoodJournalEntry> entries) {
		if (entries == null) {
			_entries.clear();
		} else {
			_entries = entries;
		}
	}

	public String toString() {
		return new ReflectionToStringBuilder(this).toString();
	}
}
